﻿using LightCAD.Core;
using LightCAD.Runtime;
using SkiaSharp;
using SkiaSharp.Views.Desktop;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LightCAD.UI
{
    public partial class MainUI : UserControl, IMainUI
    {
        public class ActiveChangedEventArgs : EventArgs
        {
            public bool IsActive { get; set; }
            public ActiveChangedEventArgs(bool isActive)
            {
                this.IsActive = isActive;
            }
        }
        public event EventHandler<ActiveChangedEventArgs> ActiveChanged;
        private DocumentControl docCtrl;
        internal bool hasDocument;
        public MainUI()
        {
            InitializeComponent();
            this.Load += MainUI_Load;
            CommandCenter.Instance.CommandExecute += Instance_CommandExecute;

        }

        public IMainWindow ParentWin => this.Parent as IMainWindow;

        public bool IsMinimized => (this.Parent as Form).WindowState == FormWindowState.Minimized;

        SKPoint IMainUI.Location => (this.Parent as Form).Location.ToSKPoint();

        public IDocumentControl DocumentCtrl => this.docCtrl;


        private bool isActive;

        private DocumentRuntime curDocRt;
        private Label curHeader;
        public bool IsActive
        {
            get { return this.isActive; }
            set
            {
                this.isActive = value;
                ActiveChanged?.Invoke(this, new ActiveChangedEventArgs(value));

            }
        }

        private void Instance_CommandExecute(object sender, CommandExecuteEventArgs e)
        {
            if (!this.IsActive) return;//非活动不接受命令

            if (curDocRt == null) return;



        }
        private StartupPage startupView;
        private Label startupHeader;
        private void MainUI_Load(object? sender, EventArgs e)
        {
            startupHeader = CreateTabItem("主页", null);
            startupHeader.ContextMenuStrip = null;
            startupHeader.MouseClick += CurHeader_MouseClick;

            startupView = new StartupPage();
            startupView.Dock = DockStyle.Fill;
            this.Controls.Add(startupView);

            App.Current.OnUIInitilized(this);

            if (!this.hasDocument)
            {
                NewDocument();
            }
        }
        #region 'Drag'

        int posX;
        int posY;
        int left;
        int top;
        bool drag;
        bool maximized;

        private void buttonClos_Click(object sender, EventArgs e)
        {
            var form = this.Parent as Form;
            form.Close();
        }

        private void buttonMax_Click(object sender, EventArgs e)
        {
            var form = this.Parent as Form;
            if (maximized)
            {
                maximized = false;
                form.WindowState = FormWindowState.Normal;
            }
            else
            {
                maximized = true;
                form.WindowState = FormWindowState.Maximized;
            }
        }

        private void buttonMin_Click(object sender, EventArgs e)
        {
            var form = this.Parent as Form;
            form.WindowState = FormWindowState.Minimized;
        }
        private void panel1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                var form = this.Parent as Form;
                if (maximized)
                {
                    form.WindowState = FormWindowState.Normal;
                    maximized = false;
                }
                else
                {
                    form.WindowState = FormWindowState.Maximized;
                    maximized = true;
                }
            }
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            var form = this.Parent as Form;
            if (e.Button == MouseButtons.Left)
            {
                drag = true;
                posX = Cursor.Position.X;
                posY = Cursor.Position.Y;
                left = form.Left;
                top = form.Top;
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            drag = false;
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            var form = this.Parent as Form;
            if (drag)
            {
                form.Top = this.top + (Cursor.Position.Y - posY);
                form.Left = this.left + (Cursor.Position.X - posX);
            }
            form.Cursor = Cursors.Default;
        }

        #endregion

        private Label CreateTabItem(string text, object tag)
        {
            var lbl = new Label();
            lbl.AutoSize = true;
            lbl.Padding = new Padding(4, 4, 4, 4);
            lbl.Dock = DockStyle.Left;
            lbl.BorderStyle = BorderStyle.FixedSingle;
            lbl.Text = text;
            lbl.Tag = tag;
            lbl.ContextMenuStrip = this.headerCtxMenu;
            pnlHeaders.Controls.Add(lbl);
            lbl.BringToFront();
            return lbl;
        }



        private void btnOpenDrawing_Click(object sender, EventArgs e)
        {
            NewDocument();
        }
        public DocumentRuntime OpenDrawingTab(LcDocument doc)
        {
            if (docCtrl == null)
            {
                docCtrl = new DocumentControl();
                docCtrl.Dock = DockStyle.Fill;
                this.Controls.Add(docCtrl);
                docCtrl.BringToFront();
            }
            var newHeader = CreateTabItem(Path.GetFileName(doc.FilePath), null);

            var docRt = DocumentManager.CreateRt(doc, docCtrl, true);
            var drawingCtrl = docCtrl.AddDrawing(docRt);

            newHeader.Tag = docRt;
            newHeader.MouseClick += CurHeader_MouseClick;

            SetHeaderCurrent(newHeader);
            DocumentManager.SetCurrent(doc);

            return docRt;
        }


        private int nameIndex = 1;
        public DocumentRuntime NewDocument()
        {

            var drawingName = string.Format(Constants.DefaultDrawingName, nameIndex++);

            var doc = LcDocument.Create();
            doc.FilePath = drawingName;
            //doc.ModelSpace.AddCircle(new Vector2d(100, 100), 50);
            //doc.ModelSpace.AddLine(new Vector2d(100, 100), new Vector2d(200, 150));

            var docRt = OpenDrawingTab(doc);
            return docRt;
        }

        private void CurHeader_MouseClick(object? sender, MouseEventArgs e)
        {
            SetHeaderCurrent(sender);
        }
        private void SetHeaderSelected(Label header, bool selected)
        {
            if (selected)
                header.BackColor = Color.LightBlue;
            else
                header.BackColor = Color.White;
        }
        private void SetHeaderCurrent(object header)
        {
            var lbl = header as Label;
            if (lbl == curHeader) return;

            for (var i = 0; i < pnlHeaders.Controls.Count; i++)
            {
                if (pnlHeaders.Controls[i] == lbl)
                    SetHeaderSelected(lbl, true);
                else
                    SetHeaderSelected((Label)pnlHeaders.Controls[i], false);
            }

            if (lbl == startupHeader)
            {
                startupView.BringToFront();
                docCtrl.SendToBack();
            }
            else
            {
                docCtrl.BringToFront();
                startupView.SendToBack();
            }
            curHeader = lbl;

            var docRt = lbl.Tag as DocumentRuntime;
            if (docRt != curDocRt)
            {
                if (curDocRt != null)
                {
                    curDocRt.SetActive(false);
                }
                if (docRt != null)
                {
                    docRt.SetActive(true);
                }
                curDocRt = docRt;
            }
        }

        public async Task<DocumentRuntime> OpenDocument(string filePath = null)
        {
            if (filePath == null)
            {
                var filePaths = await AppRuntime.UISystem.OpenFileDialog();
                if (filePaths == null) return null;
                filePath = filePaths[0];
            }
            if (this.InvokeRequired)
            {
                var tc = new TaskCompletionSource<DocumentRuntime>();
                this.Invoke((Delegate)(() =>
                {
                    var doc = DocumentUtils.Load(filePath);
                    var docRt = OpenDrawingTab(doc);
                    tc.SetResult(docRt);
                }));
                return await tc.Task;
            }
            else
            {
                var doc = DocumentUtils.Load(filePath);
                var docRt = OpenDrawingTab(doc);
                return docRt;
            }
        }

        private void CloseDocumentAction()
        {
            this.docCtrl.RemoveDrawing(this.curDocRt);
            this.pnlHeaders.Controls.Remove(this.curHeader);
            var latestDrawing = this.docCtrl.GetLastestDrawing();
            if (latestDrawing == null)
            {
                this.curDocRt = null;
                this.curHeader = null;
            }
            else
            {
                Label lastHeader = null;
                foreach (Control ctrl in this.pnlHeaders.Controls)
                {
                    if (ctrl.Tag == latestDrawing)
                    {
                        lastHeader = ctrl as Label;
                        break;
                    }
                }
                SetHeaderCurrent(lastHeader);
            }
        }

        public void CloseDocument()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(this.CloseDocumentAction);
            }
            else
            {
                this.CloseDocumentAction();
            }
        }

        public Task<string> OpenDrawingFile()
        {
            throw new NotImplementedException();
        }

        public Task<string> SaveDrawingFile(string filePath)
        {
            throw new NotImplementedException();
        }



        public void SelectDrawingTab(LcDocument document)
        {
            throw new NotImplementedException();
        }

        private void headerCtxMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

            var name = e.ClickedItem.Name;
            if (name == "mui_CloseFile")
            {
                this.CloseDocument();
            }
            else if (name == "mui_NewWindow")
            {
                var newWinDoc = curDocRt.Document;
                CloseDocument();//会更改curDocRt
                App.Current.CreateMainWindow(newWinDoc);
            }
        }

        private void headerCtxMenu_Opening(object sender, CancelEventArgs e)
        {
            if (this.docCtrl != null)
            {
                mui_NewWindow.Visible = this.docCtrl.DrawingCount > 1;
            }
        }

        private void headerCtxMenu_Opened(object sender, EventArgs e)
        {
            var header = (sender as ContextMenuStrip).SourceControl as Label;
            SetHeaderCurrent(header);
        }
    }
}
